package com.sea.operate.controller;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.codecrane.core.controller.UploaderController;
import com.codecrane.core.power.service.DictDetailService;
import com.codecrane.core.util.DateUtils;
import com.codecrane.core.util.ExcelUtil;
import com.codecrane.core.util.ProduceStatusEnum;
import com.codecrane.core.web.Ajax;
import com.codecrane.core.web.AjaxReturn;
import com.codecrane.core.web.AjaxTableReturn;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sea.operate.entity.RelatedMaterial;
import com.sea.operate.entity.RelatedMaterialDetail;
import com.sea.operate.entity.RelatedSku;
import com.sea.operate.service.RelatedMaterialDetailService;
import com.sea.operate.service.RelatedMaterialService;
import com.sea.operate.service.RelatedSkuService;
import com.sea.product.service.ChannelService;
import com.sea.supply.entity.Produce;
import com.sea.supply.entity.ProduceDetail;
import com.sea.supply.service.ProduceService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.sl.draw.geom.Path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;

import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


/**
 *  控制器
 * @author 陈鸿飞
 *  <br/>
 *  <br/>
 */
@Controller
@RequestMapping("/sea/operate/related/materialDetail")
public class RelatedMaterialDetailController {

    @Autowired
    private RelatedMaterialService  relatedMaterialService;
    @Autowired
    private RelatedMaterialDetailService relatedMaterialDetailService;
    @Autowired
    private DictDetailService dictDetailService;
    @Autowired
    private RelatedSkuService relatedSkuService;
    @Autowired
    private ProduceService produceService;



    @RequestMapping("/editPage")
    public String editPage(Model model, @RequestParam("id") Integer id) {
        model.addAttribute("id",id);
        model.addAttribute("FLLX", dictDetailService.findByTypeCode("FLLX", null));
        model.addAttribute("MBLX", dictDetailService.findByTypeCode("MBLX", null));
        return "/sea/operate/relatedMaterial/edit";
    }
    /**
     * 修改
     *
     * @param materialDetail
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public AjaxReturn save(RelatedMaterialDetail materialDetail) {
        AjaxReturn result = Ajax.fail().setMsg("保存失败！");
        try {
            if (null != materialDetail && relatedMaterialDetailService.save(materialDetail) > 0) {
                relatedMaterialService.updateModifyTime(materialDetail.getMaterialId());
                result.setOk(true).setMsg("保存成功！");
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
            result.setMsg(e.getMessage());
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.setMsg("系统异常,请联系管理员!");
            return result;
        }
        return result;
    }

    @ResponseBody
    @RequestMapping("/findByMaterialId")
    public AjaxTableReturn findByCnd(@RequestParam(value = "limit", defaultValue = "10") int pagesize,
                                     @RequestParam(value = "offset", defaultValue = "0") int start,
                                     RelatedMaterialDetail relatedMaterialDetail) {
        start = start > 0 ? start / pagesize + 1 : 1;
        PageHelper.startPage(start, pagesize);
        List<RelatedMaterialDetail> relatedList = relatedMaterialDetailService.findByMaterialId(relatedMaterialDetail);
        PageInfo<RelatedMaterialDetail> page = new PageInfo<>(relatedList);
        return Ajax.tableDataOk(page.getTotal(), page.getList());
    }

    @RequestMapping("/importDesign")
    @ResponseBody
    public AjaxReturn importDesign( MultipartFile file,@RequestParam("materialId")Integer materialId) {
        AjaxReturn result = Ajax.fail().setMsg("上传失败！");
        try {

            if (null == file || file.isEmpty()) {
                return result.setMsg("请上传文件！！！");
            } else {
                RelatedMaterialDetail relatedMaterialDetail=new RelatedMaterialDetail();
                UploaderController upload=new UploaderController();
                AjaxReturn ajaxReturn = upload.uploadFile(file, null);
                String s = ajaxReturn.getData().toString();
                relatedMaterialDetail.setMaterialDesignFile(s);
                relatedMaterialDetail.setId(materialId);
                relatedMaterialDetailService.usave(relatedMaterialDetail);
                return result.setOk(true).setData(s).setMsg("上传成功！");
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.setMsg(e.getMessage());
            return result;
        }
    }

    @RequestMapping("/importShow")
    @ResponseBody
    public AjaxReturn importShow( MultipartFile file,@RequestParam("materialId")Integer materialId) {
        AjaxReturn result = Ajax.fail().setMsg("上传失败！");
        try {

            if (null == file || file.isEmpty()) {
                return result.setMsg("请上传文件！！！");
            } else {
                RelatedMaterialDetail relatedMaterialDetail=new RelatedMaterialDetail();
                UploaderController upload=new UploaderController();
                AjaxReturn ajaxReturn = upload.uploadFile(file, null);
                String s = ajaxReturn.getData().toString();
                relatedMaterialDetail.setMaterialShowFile(s);
                relatedMaterialDetail.setId(materialId);
                relatedMaterialDetailService.usave(relatedMaterialDetail);
                relatedMaterialService.updateModifyTime(materialId);
                return result.setOk(true).setData(s).setMsg("上传成功！");
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.setMsg(e.getMessage());
            return result;
        }
    }

    @RequestMapping(value = "/checkMaterialDetail")
    @ResponseBody
    public AjaxReturn checkMaterialDetail(@RequestParam("produceId")Integer produceId) {

        AjaxReturn result = Ajax.fail().setMsg("生成成功！");
        try {


            List<RelatedSku> relatedList = relatedSkuService.findByProduceId(produceId);
            if(relatedList.size()==0 || null==relatedList.get(0)){

                return result.setMsg("暂未获取到Listing信息");
            }else{

                Boolean flag=true;
                String errMsg="暂无查询到以下Listing辅料信息<br />";
                for (RelatedSku relatedSku:relatedList){
                    RelatedMaterial relatedMaterial=new RelatedMaterial();
                    relatedMaterial.setRelatedChannelName(relatedSku.getRelatedChannelName());
                    relatedMaterial.setRelatedListing(relatedSku.getRelatedListingName());
                    RelatedMaterial material = relatedMaterialService.findByListingChannel(relatedMaterial);
                    if(null==material){
                        errMsg+="【"+relatedSku.getRelatedListingName()+"】<br /> ";

                        flag=false;
                    }
                }
                if(flag==false){
                  return  result.setOk(false).setMsg(errMsg);
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            result.setMsg("系统异常,请联系管理员!");
            return result;
        }
        return result;
    }

    @RequestMapping(value = "/exportFnSku")
    @ResponseBody
    public AjaxReturn exportFnSku(@RequestParam("produceId") Integer produceId) {
        AjaxReturn result = Ajax.fail().setMsg("生成失败！");
        try {
            List<RelatedSku> relatedSkuList = relatedSkuService.findRelatedFileByProduceId(produceId);
            Produce produce = produceService.findById(produceId);
            if (relatedSkuList.size() == 0 || null == relatedSkuList.get(0)) {

                return result.setMsg("请检查产品标是否存在!");
            } else {
                List<String> fileUrls = new ArrayList<>();
                String errMsg="";
                for (RelatedSku relatedSku : relatedSkuList) {
                    System.out.println(relatedSku.getRelatedSku());
                    if (StringUtils.isNotBlank(relatedSku.getRelatedFile())) {
                        fileUrls.add(relatedSku.getRelatedFile());
                    }else {
                        String sku = relatedSku.getRelatedSku();
                        errMsg+=sku+"<br />";
                    }
                }
                if(StringUtils.isNotBlank(errMsg)){
                    return result.setMsg("暂无获取到产品标信息SKU<br />"+errMsg);
                }
                if (fileUrls.size() == 0) {
                    return result.setMsg("暂无获取到产品标信息");
                }
                ByteArrayInputStream zipInputStream = createZipStreamFromUrls(fileUrls);
                System.out.println("ZIP 文件流已生成，可用于进一步处理！");
                // 例如将流写入文件或传递给 HTTP 响应
                OSSClient ossClient = new OSSClient("http://oss-cn-beijing.aliyuncs.com",
                        "LTAI4G55LJEk8nARtrjYngou",
                        "XPbdMs0xrRGAsmKVm9VYC8bSTTuFhl");
                InputStream inputStream = zipInputStream;
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentType("application/octet-stream");
                String filename = produce.getProduceNo() + "产品标.zip";
                //获取文件后缀名
                String prefix = filename.substring(filename.lastIndexOf(".") + 1);
                // //修改后的文件名
                String fileUUIDname = UUID.randomUUID().toString();
                //修改后的文件名(带后缀)
                String NewFileName = fileUUIDname + "." + prefix;
                ossClient.putObject("cozylux", filename, inputStream, metadata);
                // 关闭OSSClient。
                ossClient.shutdown();
                Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 50);
                String url = ossClient.generatePresignedUrl("cozylux", filename, expiration).toString();
                return result.setOk(true).setMsg(url);
            }
        }catch (Exception e) {
            e.printStackTrace();
            result.setMsg("系统异常,请联系管理员!");
            return result;
        }
    }

    @RequestMapping(value = "/downloadMaterialDetail")
    @ResponseBody
    public AjaxReturn downloadMaterialDetail(@RequestParam("produceId")Integer produceId) {
        AjaxReturn result = Ajax.fail().setMsg("生成失败！");
        try {
            Produce produce = produceService.findById(produceId);
            List<RelatedSku> relatedList = relatedSkuService.findByProduceId(produceId);
            List<RelatedMaterialDetail> fileUrls = new ArrayList<>();
            for (RelatedSku relatedSku:relatedList){
                RelatedMaterial relatedMaterial=new RelatedMaterial();
                relatedMaterial.setRelatedChannelName(relatedSku.getRelatedChannelName());
                relatedMaterial.setRelatedListing(relatedSku.getRelatedListingName());
                RelatedMaterial material = relatedMaterialService.findByListingChannel(relatedMaterial);

                if(null!=material){
                    RelatedMaterialDetail m= new RelatedMaterialDetail();
                    m.setMaterialId(material.getId());
                    List<RelatedMaterialDetail> materialDetailList = relatedMaterialDetailService.findByMaterialId(m);
                    if(materialDetailList.size()!=0){
                        for(RelatedMaterialDetail materialDetail:materialDetailList){
                            if(StringUtils.isNotBlank(materialDetail.getMaterialShowFile())){
                                fileUrls.add(materialDetail);
                            }

                        }
                    }
                }
            }
            // 下载链接列表

            if(fileUrls.size()==0){
                return result.setMsg("暂无获取到辅料信息");
            }
            ByteArrayInputStream zipInputStream = createZipStreamFromUrlsMaterial(fileUrls);
            System.out.println("ZIP 文件流已生成，可用于进一步处理！");
            // 例如将流写入文件或传递给 HTTP 响应
            OSSClient ossClient=new OSSClient("http://oss-cn-beijing.aliyuncs.com",
                    "LTAI4G55LJEk8nARtrjYngou",
                    "XPbdMs0xrRGAsmKVm9VYC8bSTTuFhl");
            InputStream inputStream = zipInputStream;
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType("application/octet-stream");
            String filename = produce.getProduceNo()+"辅料.zip";
            //获取文件后缀名
            String prefix=filename.substring(filename.lastIndexOf(".")+1);
            // //修改后的文件名
            String fileUUIDname = UUID.randomUUID().toString();
            //修改后的文件名(带后缀)
            String NewFileName = fileUUIDname + "." + prefix;
            ossClient.putObject("cozylux", filename, inputStream,metadata);
            // 关闭OSSClient。
            ossClient.shutdown();
            Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 50);
            String url = ossClient.generatePresignedUrl("cozylux", filename, expiration).toString();
            result.setOk(true).setMsg(url);
        } catch (Exception e) {
            e.printStackTrace();
            result.setMsg("系统异常,请联系管理员!");
            return result;
        }
        return result;
    }


    public static ByteArrayInputStream createZipStreamFromUrls(List<String> fileUrls) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        try (ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) {
            for (String fileUrl : fileUrls) {
                addUrlFileToZip(fileUrl, zipOut);
            }
        }

        // 将 ByteArrayOutputStream 转为 ByteArrayInputStream 供调用方读取
        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    }

    private static void addUrlFileToZip(String fileUrl, ZipOutputStream zipOut) {
        try (InputStream in = new URL(fileUrl).openStream()) {
            String fileName = Paths.get(new URL(fileUrl).getPath()).getFileName().toString();
            ZipEntry zipEntry = new ZipEntry(fileName);
            zipOut.putNextEntry(zipEntry);

            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) > 0) {
                zipOut.write(buffer, 0, len);
            }
            zipOut.closeEntry();
            System.out.println("已添加文件到压缩包：" + fileName);

        } catch (IOException e) {
            System.err.println("下载失败：" + fileUrl);
            e.printStackTrace();
        }
    }


    public static ByteArrayInputStream createZipStreamFromUrlsMaterial(List<RelatedMaterialDetail> fileUrls) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        try (ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) {
            for (RelatedMaterialDetail fileUrl : fileUrls) {
                addUrlFileToZipMaterial(fileUrl, zipOut);
            }
        }

        // 将 ByteArrayOutputStream 转为 ByteArrayInputStream 供调用方读取
        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    }

    private static void addUrlFileToZipMaterial(RelatedMaterialDetail fileUrl, ZipOutputStream zipOut) {
        try (InputStream in = new URL(fileUrl.getMaterialShowFile()).openStream()) {
            String fileName = Paths.get(new URL(fileUrl.getMaterialShowFile()).getPath()).getFileName().toString();
            String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
            ZipEntry zipEntry = new ZipEntry(fileUrl.getMaterialFL()+"."+prefix);
            zipOut.putNextEntry(zipEntry);

            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) > 0) {
                zipOut.write(buffer, 0, len);
            }
            zipOut.closeEntry();
            System.out.println("已添加文件到压缩包：" + fileUrl.getMaterialFL());

        } catch (IOException e) {
            System.err.println("下载失败：" + fileUrl);
            e.printStackTrace();
        }
    }



    //发送响应流方法
    public void setResponseHeader(HttpServletResponse response, String fileName) {
        try {
            try {
                fileName = new String(fileName.getBytes(),"ISO8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            response.setContentType("application/octet-stream;charset=ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
